package com.winning.devops.batch.utils;

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.DatabaseDriver;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.Properties;

/**
 * 数据库连接工具类
 *
 * @author chensj
 * @date 2019-09-16 15:09
 */
public class ConnectionUtils {


    private static String username;
    private static String password;
    private static String jdbcUrl;
    private static String driverClassName;
    private static DataSource dataSource;

    /**
     * 初始化数据库参数
     *
     * @param username        数据库用户名
     * @param password        数据库密码
     * @param jdbcUrl         数据库url
     * @param driverClassName 数据库连接class
     */
    private static void initDatasourceParam(String username, String password, String jdbcUrl, String driverClassName) {
        ConnectionUtils.username = username;
        ConnectionUtils.password = password;
        ConnectionUtils.jdbcUrl = jdbcUrl;
        ConnectionUtils.driverClassName = driverClassName;
    }

    /**
     * 初始化数据库连接池
     */
    private static void initDataSource() {
        // 创建基础hikari数据源
        DataSourceBuilder<HikariDataSource> hikariDataSourceBuilder =
                DataSourceBuilder.create().type(HikariDataSource.class);
        HikariDataSource hikariDataSource = hikariDataSourceBuilder
                .driverClassName(DatabaseDriver.fromJdbcUrl(ConnectionUtils.jdbcUrl).getDriverClassName())
                .url(ConnectionUtils.jdbcUrl)
                .username(ConnectionUtils.username)
                .password(ConnectionUtils.password).build();

        //配置Hikari连接池
        //update自动提交设置
        hikariDataSource.setAutoCommit(true);
        //连接查询语句设置
        hikariDataSource.setConnectionTestQuery(
                DatabaseDriver.fromJdbcUrl(ConnectionUtils.jdbcUrl).getValidationQuery());
        //连接超时时间设置
        hikariDataSource.setConnectionTimeout(3000);
        //连接空闲生命周期设置
        hikariDataSource.setIdleTimeout(3000);
        //执行查询启动设置
        hikariDataSource.setIsolateInternalQueries(false);
        //连接池允许的最大连接数量
        hikariDataSource.setMaximumPoolSize(3000);
        //检查空余连接优化连接池设置时间,单位毫秒
        hikariDataSource.setMaxLifetime(1800000);
        //连接池保持最小空余连接数量
        hikariDataSource.setMinimumIdle(10);
        //连接池名称
        hikariDataSource.setPoolName("hikariPool");
        ConnectionUtils.dataSource = hikariDataSource;
    }

    /**
     * 获取数据库连接
     *
     * @param username        数据库用户名
     * @param password        数据库密码
     * @param jdbcUrl         数据库url
     * @param driverClassName 数据库连接class
     * @return connection
     * @throws SQLException 数据库连接异常
     */
    public static Connection getConnection(String username, String password, String jdbcUrl, String driverClassName) throws SQLException {
        initDatasourceParam(username, password, jdbcUrl, driverClassName);
        initDataSource();
        return ConnectionUtils.dataSource.getConnection();
    }

    /**
     * 获取数据库
     *
     * @param username        数据库用户名
     * @param password        数据库密码
     * @param jdbcUrl         数据库url
     * @param driverClassName 数据库连接class
     * @return dataSource
     */
    public static DataSource getDataSource(String username, String password, String jdbcUrl, String driverClassName) {
        initDatasourceParam(username, password, jdbcUrl, driverClassName);
        initDataSource();
        return ConnectionUtils.dataSource;
    }

    /**
     * 获取数据库连接池
     *
     * @return dataSource
     */
    public static DataSource getDataSource() {
        if (ConnectionUtils.dataSource == null) {
            throw new RuntimeException("请先初始化数据库参数");
        } else {
            return ConnectionUtils.dataSource;
        }
    }

    /**
     * 数据库关闭
     */
    public static void closeDatasource() {
        if (ConnectionUtils.dataSource != null) {
            HikariDataSource hikariDataSource = (HikariDataSource) ConnectionUtils.dataSource;
            hikariDataSource.close();
            ConnectionUtils.username = null;
            ConnectionUtils.password = null;
            ConnectionUtils.jdbcUrl = null;
            ConnectionUtils.driverClassName = null;
            ConnectionUtils.dataSource = null;
        }
    }

    /**
     * 关闭所有
     *
     * @param conn 连接
     * @param ps   ps
     * @param rs   rs
     */
    public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
                rs = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (ps != null) {
            try {
                ps.close();
                ps = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
                conn = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    public static void main(String[] args) {
        String jdbcUrl = "jdbc:sqlserver://172.17.1.241:1433;DatabaseName=devops20";
        System.out.println(DatabaseDriver.fromJdbcUrl(jdbcUrl).getDriverClassName());
        String username = "sa";
        String password = "sql2k!@";
        try {
            Connection connection = getConnection(username, password, jdbcUrl,
                    DatabaseDriver.fromJdbcUrl(jdbcUrl).getDriverClassName());
            Properties info = connection.getClientInfo();
            Enumeration<?> enumeration = info.propertyNames();
            while (enumeration.hasMoreElements()) {
                System.out.println(enumeration.nextElement());
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


}
